home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / graphics / fig2mf / fig2MF.c < prev    next >
C/C++ Source or Header  |  1993-03-18  |  10KB  |  630 lines

  1. /* 
  2.  *  fig2MF -- convert fig to mfpic METAFONT code
  3.  *
  4.  *  copyright (c) 1993 Anthony Starks (ajs@merck.com)
  5.  *  You may do anything you want with this code except sell it
  6.  *  or claim that you wrote it.
  7.  *
  8.  *  Version 0.00 --     Incorporate Tobin's small suggestions
  9.  *  Version 0.01 --     Change scaling to inches, 
  10.  *            default [x-y]scale is 1/8 inch
  11.  *            slight format changes in cinit()
  12.  *  Version 0.02 --    Fixed pen switching bug
  13.  *  Version 0.03 --    Support new arcthree mode
  14.  *  Version 0.04 --    Token support for text
  15.  */
  16.  
  17. #include <stdio.h>
  18.  
  19. #define put_msg(x)    fputs(x, stderr); \
  20.             fprintf(stderr, \
  21.             " at line %d of file \"%s\" \n", line, curfile)
  22. #define dofill()    1.2-((double)area_fill/(double)FILL_BLACK)
  23. #define dopen(x)    ((x-1)*PEN_INCR)+DEF_PEN
  24. #define VERSION        0.04
  25. #define BUF_SIZE    1024
  26. #define O_ELLIPSE    1
  27. #define O_POLYLINE    2
  28. #define O_SPLINE    3
  29. #define O_TEXT        4
  30. #define O_ARC        5
  31. #define O_COMP        6
  32. #define O_ECOMP        -6
  33. #define FILL_BLACK    21
  34. #define N_CURVE        11
  35. #define N_POLYLINE    12
  36. #define N_ELLIPSE    19
  37. #define N_ARC        20
  38. #define DEF_PEN        0.5
  39. #define PEN_INCR    0.10
  40. #define DEF_BFILE    "graphbase.mf"
  41. char buf[BUF_SIZE];
  42.  
  43. typedef struct {
  44.     char *keyword;
  45.     double *value;
  46. } Options;
  47.  
  48. int line;
  49. double ppi;
  50. double mag;
  51. double code;
  52. double mfpen;
  53. double xscale;
  54. double yscale;
  55. double xl;
  56. double yl;
  57. double xu;
  58. double yu;
  59. double maxy;
  60. char *progname;
  61. char *curfile;
  62. char basefile[100];
  63.  
  64. Options opts[]  = {
  65. {"-mag",    &mag},
  66. {"-code",    &code},
  67. {"-pen",    &mfpen},
  68. {"-xscale",    &xscale},
  69. {"-yscale",    &yscale},
  70. {"-xneg",    &xl},
  71. {"-xpos",    &xu},
  72. {"-yneg",    &yl},
  73. {"-ypos",    &yu},
  74. {"-top",    &maxy},
  75. {NULL,        NULL}
  76. };
  77.  
  78.  
  79. main(argc, argv)
  80. int             argc;
  81. char          *argv[];
  82. {
  83.     FILE           *fp;
  84.     int i;
  85.     progname = argv[0];
  86.     curfile = "Standard Input";
  87.     strcpy(basefile, DEF_BFILE);
  88.     line=1;
  89.     mag=1000.0;
  90.     code=32.0;
  91.     mfpen=0.5;
  92.     xscale=0.125;
  93.     yscale=0.125;
  94.     xl=0.0;
  95.     xu=8.0;
  96.     yl=0.0;
  97.     yu=8.0;
  98.     maxy=8.0;
  99.  
  100.     if (argc < 2)
  101.         process("-");
  102.     else
  103.     {
  104.         for (i=1; i < argc; i++)
  105.         {
  106.             parse(argv[i]);
  107.         }
  108.     }
  109.  
  110.     ffin();
  111.     exit(0);
  112.  
  113. }
  114.  
  115. parse(s)
  116. char *s;
  117. {
  118.     int i, n;
  119.     char *strchr();
  120.     double atof();
  121.  
  122.     for (i=0; opts[i].keyword != NULL; i++)
  123.     {
  124.         if (strncmp(s, opts[i].keyword, strlen(opts[i].keyword)) == 0)
  125.         {
  126.             *opts[i].value = atof(strchr(s, '=')+1);
  127.             return;
  128.         }
  129.     }
  130.     process(s);
  131. }
  132.  
  133. process(filename)
  134. char *filename;
  135. {
  136.     FILE *fp;
  137.  
  138.     int coord_sys, object;
  139.  
  140.     if (filename[0] == '-')
  141.     {
  142.         curfile = "Standard Input";
  143.         fp = stdin;
  144.     }
  145.     else
  146.     {
  147.         curfile=filename;
  148.         if ((fp = fopen(filename, "r")) == NULL)
  149.         {
  150.             fprintf(stderr, 
  151.             "%s: cannot open the input file \"%s\"\n",
  152.             progname, filename);
  153.             return;
  154.         }
  155.     }
  156.  
  157.     line = 1;
  158.     fgets(buf, sizeof(buf), fp);
  159.     if (strncmp(buf, "#FIG 2.1", 8) != 0)
  160.     {
  161.         put_msg("Not a fig 2.1 file");
  162.         return;
  163.     }
  164.     get_line(fp);
  165.     if (sscanf(buf, "%lf%d\n", &ppi, &coord_sys) != 2)
  166.     {
  167.         put_msg("Incomplete data");
  168.         return;
  169.     }
  170.     cinit();
  171.     while (get_line(fp) > 0)
  172.     {
  173.         if (sscanf(buf, "%d", &object) != 1)
  174.         {
  175.             put_msg("Incorrect format");
  176.             return;
  177.         }
  178.         switch(object)
  179.         {
  180.             case O_COMP:
  181.             case O_ECOMP:
  182.                 break;
  183.             case O_ELLIPSE:
  184.                 ellipse(fp);
  185.                 break;
  186.             case O_POLYLINE:
  187.                 polyline(fp);
  188.                 break;
  189.             case O_SPLINE:
  190.                 curve(fp);
  191.                 break;
  192.             case O_TEXT:
  193.                 text(fp);
  194.                 break;
  195.             case O_ARC:
  196.                 arc(fp);
  197.                 break;
  198.             default:
  199.                 fprintf(stderr, "%d is an ", object);
  200.                 put_msg("unknown object");
  201.                 break;
  202.         }
  203.     }
  204.     cfin();
  205.     if (fp != stdin) fclose(fp);
  206.  
  207. }
  208.  
  209. polyline(fp)
  210. FILE *fp;
  211. {
  212.     int    c, 
  213.         n, 
  214.         type, 
  215.         subtype, 
  216.         style, 
  217.         radius, 
  218.         thickness, 
  219.         color, 
  220.         depth,
  221.         pen, 
  222.         area_fill,
  223.         fa, 
  224.         ba, 
  225.         at, 
  226.         as, 
  227.         eflag;
  228.  
  229.     double    style_val, 
  230.         athick, 
  231.         awidth, 
  232.         aht;
  233.  
  234.     char    epsfile[100];
  235.  
  236.     c = 0;
  237.     n = sscanf(buf, "%d%d%d%d%d%d%d%d%lf%d%d%d",
  238.         &type,
  239.         &subtype,
  240.         &style,
  241.         &thickness,
  242.         &color,
  243.         &depth,
  244.         &pen,
  245.         &area_fill,
  246.         &style_val,
  247.         &radius,
  248.         &fa,
  249.         &ba);
  250.  
  251.     if (n != N_POLYLINE)
  252.     {
  253.         put_msg("Malformed polyline");
  254.         return c;
  255.     }
  256.     if (subtype == 5) fscanf(fp, "%d%s", &eflag, epsfile);
  257.     if (fa) fscanf(fp, "%d%d%lf%lf%lf\n", &at, &as, &athick, &awidth, &aht);
  258.     if (ba) fscanf(fp, "%d%d%lf%lf%lf\n", &at, &as, &athick, &awidth, &aht);
  259.     if (thickness > 1) 
  260.         printf("  pickup pencircle scaled %.2lfpt;\n", 
  261.             dopen(thickness));
  262.     if (area_fill == FILL_BLACK)
  263.         printf("  cycleshade(0, false,\n");
  264.     else if (area_fill < FILL_BLACK && area_fill > 0)
  265.         printf("  cycleshade(%lfpt, false,\n", dofill());
  266.     else
  267.         printf("  curve(false, false,\n");
  268.     c = coords(type, fp);
  269.     if (thickness > 1) 
  270.         printf("  pickup pencircle scaled %.2lfpt;\n", 
  271.             mfpen);
  272.  
  273.     return c;
  274. }
  275.  
  276.  
  277. curve(fp)
  278. FILE *fp;
  279. {
  280.     int    n, 
  281.         c,
  282.         i,
  283.         type, 
  284.         style, 
  285.         subtype, 
  286.         thickness, 
  287.         color, 
  288.         depth, 
  289.         pen, 
  290.         area_fill,
  291.             fa, 
  292.         ba,
  293.         at,
  294.         as;
  295.  
  296.     double    style_val, 
  297.         athick, 
  298.         awidth, 
  299.         aht, 
  300.         z;
  301.  
  302.     c = 0;
  303.     n = sscanf(buf, "%d%d%d%d%d%d%d%d%lf%d%d",
  304.            &type,
  305.            &subtype,
  306.            &style,
  307.            &thickness,
  308.            &color,
  309.            &depth,
  310.            &pen,
  311.            &area_fill,
  312.            &style_val,
  313.            &fa,
  314.            &ba);
  315.     if (n != N_CURVE)
  316.     {
  317.         put_msg("Malformed spline");
  318.         return c;
  319.     }
  320.     if (fa) fscanf(fp, "%d%d%lf%lf%lf\n", &at, &as, &athick, &awidth, &aht);
  321.     if (ba) fscanf(fp, "%d%d%lf%lf%lf\n", &at, &as, &athick, &awidth, &aht);
  322.     if (thickness > 1) 
  323.         printf("  pickup pencircle scaled %.2lfpt;\n", 
  324.             dopen(thickness));
  325.     if (area_fill == FILL_BLACK)
  326.         printf("  cycleshade(0, true,\n");
  327.     else if (area_fill < FILL_BLACK && area_fill > 0)
  328.         printf("  cycleshade(%lfpt, true,\n", dofill());
  329.     else
  330.         printf("  curve(true, false,\n");
  331.     c = coords(type, fp);
  332.     if (subtype > 1)
  333.         for (i=0; i < c*4; i++)
  334.             fscanf(fp, "%lf", &z);
  335.     if (thickness > 1) 
  336.         printf("  pickup pencircle scaled %.2lfpt;\n", mfpen);
  337.     return c;
  338. }
  339.  
  340. coords(obj, fp)
  341. int obj;
  342. FILE *fp;
  343. {
  344.     int c, n, x, y;
  345.  
  346.     c = 0;
  347.     if ((n = fscanf(fp, "%d%d", &x, &y)) != 2)
  348.     {
  349.         put_msg("Incomplete object");
  350.         return c;
  351.     }
  352.     printf("       (%lf, %lf)", x/ppi, maxy-(y/ppi));
  353.     for (c = 1;;)
  354.     {
  355.         if (fscanf(fp, "%d%d", &x, &y) != 2)
  356.         {
  357.             put_msg("Incomplete object"); 
  358.             fputs(buf, stderr);
  359.             return c;
  360.         }
  361.         if (x == 9999) break;
  362.         printf(",\n       (%lf, %lf)", x/ppi, maxy-(y/ppi));
  363.         c++;
  364.     }
  365.     printf(");\n");
  366.     return c;
  367.  
  368. }
  369.  
  370. ellipse(fp)
  371. FILE *fp;
  372. {
  373.     int     n,
  374.          type,
  375.          subtype,
  376.          style,
  377.          thickness,
  378.          color,
  379.          depth,
  380.          pen,
  381.          area_fill,
  382.          dir,
  383.          cx,
  384.          cy,
  385.          rx,
  386.          ry,
  387.          sx,
  388.          sy,
  389.          ex,
  390.          ey;
  391.  
  392.     double    style_val, 
  393.         angle;
  394.  
  395.     n = sscanf(buf, "%d%d%d%d%d%d%d%d%lf%d%lf%d%d%d%d%d%d%d%d",
  396.         &type,
  397.         &subtype,
  398.         &style,
  399.         &thickness,
  400.         &color,
  401.         &depth,
  402.         &pen,
  403.         &area_fill,
  404.         &style_val,
  405.         &dir,
  406.         &angle,
  407.         &cx,
  408.         &cy,
  409.         &rx,
  410.         &ry,
  411.         &sx,
  412.         &sy,
  413.         &ex,
  414.         &ey);
  415.     if (n != N_ELLIPSE)
  416.     {
  417.         put_msg("Malformed circle or ellipse");
  418.         return;
  419.     }
  420.  
  421.     if (thickness > 1) 
  422.         printf("  pickup pencircle scaled %.2lfpt;\n", 
  423.             dopen(thickness));
  424.  
  425.     if (subtype == 3 || subtype == 4)
  426.     {
  427.         if (area_fill == FILL_BLACK)
  428.             printf("  circshade(0, ");
  429.         else if (area_fill < FILL_BLACK && area_fill > 0)
  430.             printf("  circshade(%lfpt, ", dofill());
  431.         else
  432.             printf("  circle(");
  433.         printf("(%lf,%lf),%lf);\n", 
  434.             cx/ppi, maxy-(cy/ppi), rx/ppi);
  435.     }
  436.     else if (subtype == 1 || subtype == 2)
  437.     {
  438.         if (area_fill == FILL_BLACK)
  439.             printf("  ellshade(0, ");
  440.         else if (area_fill < FILL_BLACK && area_fill > 0)
  441.             printf("  ellshade(%lfpt, ", dofill());
  442.         else
  443.             printf("  ellipse(");
  444.         printf("(%lf,%lf),%lf,%lf,0);\n",
  445.             cx/ppi, maxy-(cy/ppi), rx/ppi, ry/ppi);
  446.     }
  447.     if (thickness > 1) 
  448.         printf("  pickup pencircle scaled %.2lfpt;\n", mfpen);
  449.  
  450. }
  451.  
  452. arc(fp)
  453. FILE *fp;
  454. {
  455.  
  456.     int    n,
  457.         type,
  458.         subtype,
  459.         style,
  460.         thickness,
  461.         color,
  462.         depth,
  463.         pen,
  464.         fill,
  465.         dir,
  466.         fa,
  467.         ba,
  468.         x1,
  469.         y1,
  470.         x2,
  471.         y2,
  472.         x3,
  473.         y3;
  474.  
  475.     double    style_val, 
  476.         cx, 
  477.         cy;
  478.  
  479.  
  480.     n = sscanf(buf, "%d%d%d%d%d%d%d%d%lf%d%d%d%lf%lf%d%d%d%d%d%d",
  481.         &type,
  482.         &subtype,
  483.         &style,
  484.         &thickness,
  485.         &color,
  486.         &depth,
  487.         &pen,
  488.         &fill,
  489.         &style_val,
  490.         &dir,
  491.         &fa,
  492.         &ba,
  493.         &cx,
  494.         &cy,
  495.         &x1,
  496.         &y1,
  497.         &x2,
  498.         &y2,
  499.         &x3,
  500.         &y3);
  501.  
  502.     if (fa) get_line(fp);
  503.     if (ba) get_line(fp);
  504.  
  505.     if (n != N_ARC)
  506.     {
  507.         put_msg("Malformed arc");
  508.         return n;
  509.     }
  510.     if (thickness > 1) 
  511.         printf("  pickup pencircle scaled %.2lfpt;\n", 
  512.             dopen(thickness));
  513.  
  514.     printf("  arcthree((%lf,%lf), (%lf,%lf), (%lf,%lf));\n",
  515.         x1/ppi,
  516.         maxy-(y1/ppi),
  517.         x2/ppi,
  518.         maxy-(y2/ppi),
  519.         x3/ppi,
  520.         maxy-(y3/ppi));
  521.  
  522.     if (thickness > 1) 
  523.         printf("  pickup pencircle scaled %.2lfpt;\n", 
  524.             mfpen);
  525.  
  526.     return n;
  527.  
  528. }
  529.  
  530. text(fp)
  531. FILE *fp;
  532. {
  533.  
  534.     int    n,
  535.         x,
  536.         y;
  537.  
  538.     int    type,
  539.         font,
  540.         size,
  541.         pen, 
  542.         color,
  543.         depth, 
  544.         filler, 
  545.         angle, 
  546.         flags,
  547.         ht, 
  548.         len;
  549.     char     text[80],
  550.         junk[2],
  551.         *p, 
  552.         *strrchr();
  553.  
  554.     n = sscanf(buf, "%*d%d%d%d%d%d%d%lf%d%d%d%d%d%[^\1]%[\1]",
  555.             &type,
  556.             &font,
  557.             &size,
  558.             &pen,
  559.             &color,
  560.             &depth,
  561.             &angle,
  562.             &flags,
  563.             &ht,
  564.             &len,
  565.             &x,
  566.             &y,
  567.             text,
  568.             junk);
  569.     if ((n != 13) && (n != 14))
  570.     {
  571.         put_msg("Bad Text");
  572.         return 0;
  573.     }
  574.     p = &text[1];
  575.     printf("%% label((%lf,%lf),%s)\n", x/ppi, maxy-(y/ppi), p);
  576.     return(strlen(text));
  577. }
  578.  
  579. cinit()
  580. {
  581.     static int once = 0;
  582.     static int curchar;
  583.     if (++once == 1) 
  584.     {
  585.         curchar = (int)code;
  586.         printf("%%\n%% %s version %.2lf --- Preamble\n%%\n", 
  587.             progname, VERSION);
  588.         printf("mag:=%g/1000; input %s; code:=%g;\n", 
  589.             mag, basefile, code);
  590.         printf("mfpicenv;\ninterim hdwdr:=1; interim hdten:=1;\n");
  591.         printf("interim penwd:=%.2lfpt;\npickup pencircle scaled penwd;\n", mfpen);
  592.     }
  593.     printf("%%\n%% %s (char %d)\n%%\n", curfile, ++curchar);
  594.     printf("xscale:=%.3lf; yscale:=%.3lf; bounds(%.3lf,%.3lf,%.3lf,%.3lf);\n", 
  595.         xscale, yscale, xl, xu, yl, yu);
  596.     printf("beginchar(incr code,xscale*(xpos-xneg)*in#,yscale*(ypos-yneg)*in#,0);\n");
  597.     printf("  setztr;\n");
  598.     printf("  pickup pencircle scaled %.2lfpt;\n", mfpen);
  599. }
  600.  
  601. cfin()
  602. {
  603.     printf("endchar;\n");
  604. }
  605.  
  606. ffin()
  607. {
  608.     if (line > 1) printf("endmfpicenv;\nend.\n");
  609. }
  610.  
  611. get_line(fp)
  612.     FILE           *fp;
  613. {
  614.     while (1)
  615.     {
  616.         if (NULL == fgets(buf, BUF_SIZE, fp))
  617.         {
  618.             return (-1);
  619.         }
  620.         line++;
  621.         if (*buf != '\n' && *buf != '#')
  622.             return (1);
  623.         /* Skip empty and comment lines */
  624.     }
  625. }
  626.  
  627.  
  628.  
  629.  
  630.